#include <hildon/hildon-banner.h>

#include "locationinfowidget.h"

LocationInfo::LocationInfo(QObject *parent): QObject(parent)
{
    status = new QString("No Fix");
    satellites = 0;
    altitude = -1;
    speed = -1;
    latitude = 0.0;
    longitude = 0.0;

    control = location_gpsd_control_get_default();
    if (control)
        location_gpsd_control_start(control);

    device = (LocationGPSDevice*)g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL);
    if (device) {
        g_signal_connect(device, "changed",
                          G_CALLBACK(LocationInfo::locationChanged), this);
        g_signal_connect(device, "connected",
                          G_CALLBACK(LocationInfo::locationConnected), this);
        g_signal_connect(device, "disconnected",
                          G_CALLBACK(LocationInfo::locationDisconnected), this);
    }
}

LocationInfo::~LocationInfo()
{
    if (device)
        g_object_unref(device);

    if (control)
        location_gpsd_control_stop(control);
}

void LocationInfo::updateStatus(LocationGPSDeviceStatus status)
{
    if (status == LOCATION_GPS_DEVICE_STATUS_NO_FIX) {
        *LocationInfo::status = "No Fix";
    } else {
        *LocationInfo::status = "Fixed";
    }
}

void LocationInfo::updateDeviceFix(LocationGPSDeviceFix *fix)
{
    /* Testing if the altitude field of LocationGPSDeviceFix is valid. */
    if (fix->mode == LOCATION_GPS_DEVICE_MODE_3D &&
        fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) {
        altitude = fix->altitude;
    }else {
        altitude = -1;
    }

    /* Testing if the latitude and longitude fields of LocationGPSDeviceFix are valid. */
    if ((fix->mode == LOCATION_GPS_DEVICE_MODE_3D ||
         fix->mode == LOCATION_GPS_DEVICE_MODE_2D) &&
        fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) {
            latitude = fix->latitude;
            longitude = fix->longitude;
            emit positionChanged(longitude, latitude);
        }

    /* Testing if the speed field of LocationGPSDeviceFix is valid. */
    if (fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) {
        speed = fix->speed;
    }else {
        speed = -1;
    }
}

void LocationInfo::locationChanged(LocationGPSDevice *device,
                                         gpointer userdata)
{
    LocationInfo *widget = static_cast<LocationInfo *>(userdata);

    widget->updateStatus(device->status);
    widget->satellites = device->satellites_in_use;
    widget->updateDeviceFix(device->fix);
}

void LocationInfo::locationConnected(LocationGPSDevice *device,
                                           gpointer userdata)
{
    Q_UNUSED(device);
    Q_UNUSED(userdata);
    hildon_banner_show_information(NULL, NULL, "GPS Connected");
}

void LocationInfo::locationDisconnected(LocationGPSDevice *device,
                                              gpointer userdata)
{
    Q_UNUSED(device);
    Q_UNUSED(userdata);
    hildon_banner_show_information(NULL, NULL, "GPS Disconnected");
}
